import { group } from '@angular/animations';
import { CommonModule } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, inject, OnDestroy, OnInit, TemplateRef, ViewChild } from '@angular/core';
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';
import { AfMessageService } from '@core';
import { STColumn, STComponent } from '@delon/abc/st';
import { dateTimePickerUtil as dateUtil, getTimeDistance } from '@delon/util';
import { SharedModule } from '@shared';
import { NzFlexModule } from 'ng-zorro-antd/flex';
import { NzLayoutModule } from 'ng-zorro-antd/layout';
import { zip } from 'rxjs';

import { AfSystemService, EXECUTE_TYPES, STARTUP_TYPES } from '../af-system.service';

@Component({
  selector: 'app-schedule',
  standalone: true,
  imports: [SharedModule, NzLayoutModule, NzFlexModule],
  templateUrl: './schedule.component.html',
  styleUrl: './schedule.component.less',
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class ScheduleComponent implements OnInit, OnDestroy {
  private readonly cdr = inject(ChangeDetectorRef);
  private readonly sysSrv = inject(AfSystemService);
  private readonly msgSrv = inject(AfMessageService);
  private readonly fb = inject(UntypedFormBuilder);
  private readonly router = inject(Router);
  private intervalId: any; // 保存 setInterval 的返回值

  constructor() {}
  ngOnInit(): void {
    this.initLoadData();
    this.autoReSizeFixWindowHeight();
    // 每隔1分钟，重写加载作业列表
    this.startTimer(60);
  }

  startTimer(secord: number) {
    this.intervalId = setInterval(() => {
      this.loadJobList(true);
    }, secord * 1000); // 每 5 秒执行一次
  }

  ngOnDestroy(): void {
    clearInterval(this.intervalId); // 组件销毁时清除定时器
  }

  startTypes = STARTUP_TYPES;
  executeTypes = EXECUTE_TYPES;
  groupSearch = '';
  groupList: any[] = [];
  currentGroupList: any[] = [];
  currentGroup: any = '';
  groupListChange(value: any) {
    if (value) {
      this.currentGroupList = this.groupList.filter(item => item.groupName.includes(value));
    } else {
      this.currentGroupList = this.groupList;
    }

    // console.log('onGroupChange', value);
    if (this.currentGroupList.length > 0) {
      this.currentGroup = this.currentGroupList[0];
      this.getJobList(this.currentGroupList[0]);
    }
    // 过滤作业
    this.cdr.detectChanges();
    console.log('currentGroupList', this.currentGroup);
  }

  initLoadData() {
    zip(this.sysSrv.getScheduleGroup(), this.sysSrv.getScheduleJob(true)).subscribe(([res1, res2]: [any, any]) => {
      if (res2.status) {
        this.jobList = res2.data;
      }
      if (res1.status) {
        this.groupList = res1.data;
        if (this.groupList.length > 0) {
          this.groupList.unshift({ groupCode: 'all', groupName: '全部', sortIndex: 0 });
        }
        this.groupListChange('');
      }
      this.cdr.detectChanges();
    });
  }

  jobList: any[] = [];
  currentJobList: any[] = [];
  loadJobList(filtered: boolean = false) {
    this.jobList = [];
    this.sysSrv.getScheduleJob(false).subscribe(res => {
      console.log('loadJobList', res);
      if (res.status) {
        this.jobList = res.data;
        if (filtered) {
          this.jobListChange();
        }
      }
      this.cdr.detectChanges();
    });
  }

  isLoading = false;
  getJobList(group: any) {
    this.currentGroup = group;
    this.filterJobList(group.groupCode, this.searchJobName, this.searchScheduleStatus);
  }

  filterJobList(groupCode: any, jobName: any, scheduleStatus: any) {
    this.currentJobList = this.jobList.filter((item: any) => {
      if (
        (item.groupCode === groupCode || groupCode === 'all') &&
        (!jobName || item.name.includes(jobName)) &&
        (!scheduleStatus || item.scheduledStatus.includes(scheduleStatus))
      ) {
        return true;
      } else {
        return false;
      }
    });

    // console.log('filterJobList', this.currentJobList);
    this.cdr.detectChanges();
  }

  searchJobName = '';
  searchScheduleStatus = '';
  jobListChange() {
    this.filterJobList(this.currentGroup.groupCode, this.searchJobName, this.searchScheduleStatus);
  }

  newGroupCode = '';
  newGroupName = '';
  createGroup(tpl: TemplateRef<{}>) {
    this.msgSrv.form_confirm2(
      '新增作业分组',
      tpl,
      () => {
        if (!this.newGroupCode) {
          this.msgSrv.msg_warning('请先输入作业分组编码');
          return;
        }
        if (!this.newGroupName) {
          this.msgSrv.msg_warning('请先输入作业分组名称');
          return;
        }
        const newItem = { groupCode: this.newGroupCode, groupName: this.newGroupName, sortIndex: this.maxGroupSortIndex() };
        this.sysSrv.saveScheduleGroup(newItem).subscribe(res => {
          console.log('createGroup', res);
          if (res.status) {
            // this.currentGroupList.push(newItem);
            this.groupList.push(newItem);
          }
          this.cdr.detectChanges();
        });
      },
      () => {},
      500,
      'info'
    );
  }

  maxGroupSortIndex(): number {
    if (!this.groupList || this.groupList.length === 0) {
      return 1; // 如果数组为空，则返回 1
    }

    const maxSortIndex = Math.max(...this.groupList.map(item => item.sortIndex));
    return maxSortIndex + 1;
  }

  editGroup(item: any, tpl: TemplateRef<{}>) {
    if (item.groupCode === 'all') {
      return;
    }
    this.newGroupName = item.groupName;
    this.msgSrv.form_confirm2(
      '编辑对话名称',
      tpl,
      () => {
        if (!this.newGroupName) {
          this.msgSrv.msg_warning('请先输入新分组名称');
          return;
        }
        const newItem = { ...item, groupName: this.newGroupName };
        this.sysSrv.saveScheduleGroup(newItem).subscribe(res => {
          console.log('editGroup', res);
          if (res.status) {
            item.groupName = this.newGroupName;
          }
          this.cdr.detectChanges();
        });
      },
      () => {},
      500,
      'info'
    );
  }

  deleteGroup(code: any) {
    if (code === 'all') {
      return;
    }
    this.msgSrv.form_delete(
      '请确认是否要删除作业组？',
      '点击‘确定’立马删除',
      () => {
        this.sysSrv.deleteScheduleGroup(code).subscribe(res => {
          console.log('this.deleteGroup', res);
          if (res) {
            this.groupList = this.groupList.filter(item => item.groupCode != code);
            this.currentGroupList = this.currentGroupList.filter(item => item.groupCode != code);
          }
          this.cdr.detectChanges();
        });
      },
      () => {}
    );
  }

  @ViewChild('st', { static: false }) st!: STComponent;

  columns: STColumn[] = [
    { title: '作业编码', index: 'code', width: '150px', sort: true },
    { title: '作业名称', index: 'name', width: '180px', sort: true },
    { title: '调用表达式', index: 'cron', width: '100px' },

    { title: '下次运行时间', index: 'scheduledNextTime', width: '200px' },
    // { title: '作业日志', index: 'scheduledInfo' },

    // { title: '上次开始执行', index: 'jobStartTime', type: 'date' },
    {
      title: '运行状态',
      index: 'jobStatus',
      type: 'badge',
      width: '90px',
      badge: {
        pending: { text: '待执行', color: 'success' },
        processing: { text: '执行中', color: 'processing' },
        failed: { text: '执行失败', color: 'error' }
      }
    },
    {
      title: '上次完成时间',
      index: 'jobEndTime',
      width: '200px'
    },
    { title: '执行类型', index: 'executeType', width: '75px' },
    { title: '执行程序', index: 'executeName', width: '175px' },
    { title: '执行方法', index: 'executeMethod', width: '120px' },
    { title: '请求参数', index: 'executeParam', width: '120px' },

    { title: '线程数', index: 'numberOfThread', width: '75px' },
    { title: '数据条数', index: 'numberOfData', width: '75px' },

    {
      title: '启动类型',
      index: 'startupType',
      type: 'badge',
      width: '90px',
      badge: {
        auto: { text: '自启动', color: 'success' },
        manual: { text: '手工启动', color: 'warning' },
        disable: { text: '已禁用', color: 'default' }
      }
    },
    // { title: '上次运行结果', index: 'jobResult' },
    // { title: '上次消耗时间', index: 'jobCost' },

    // { title: '备注', index: 'remark' },
    { title: '作业分组', index: 'groupCode', width: '100px' },

    { title: '总运行数', index: 'totalCount', width: '75px' },
    { title: '总消耗毫秒', index: 'totalCost', width: '95px' },
    { title: '总失败数', index: 'failedCount', width: '75px' },
    {
      title: '作业状态',
      index: 'scheduledStatus',
      width: '80px',
      fixed: 'right',
      className: 'text-center',
      type: 'tag',
      tag: {
        started: { text: '已启动', color: 'success' },
        stopped: { text: '已停止', color: 'orange' },
        disabled: { text: '已禁用', color: 'cyan' },
        failed: { text: '失败', color: 'red' }
      }
    },
    {
      title: '操作',
      width: '60px',
      fixed: 'right',
      buttons: [
        {
          text: '更多',
          children: [
            {
              text: '启动',
              iif: record => record.scheduledStatus !== 'started',
              iifBehavior: 'disabled',
              click: _record => {
                this.startJob(_record);
              }
            },
            {
              text: '停止',
              iif: record => record.scheduledStatus === 'started',
              iifBehavior: 'disabled',
              click: _record => {
                this.stopJob(_record);
              }
            },
            {
              text: '立即执行',
              iif: record => record.scheduledStatus !== 'started',
              iifBehavior: 'disabled',
              click: _record => {
                this.executeJob(_record);
              }
            },
            { text: '查看日志', icon: 'eye', click: (item: any) => this.viewLog(item) },

            {
              text: '',
              type: 'divider'
            },
            {
              text: '编辑',
              iif: record => record.scheduledStatus !== 'started',
              iifBehavior: 'disabled',
              click: _record => {
                this.drawer_open(_record);
              }
            },
            {
              text: '删除',
              iif: record => record.scheduledStatus !== 'started',
              iifBehavior: 'disabled',
              type: 'del',
              pop: {
                title: '您确定要删除此记录吗？',
                okType: 'danger',
                icon: 'star'
              },
              click: record => {
                this.deleteJob(record);
              }
            },
            {
              text: '',
              type: 'divider'
            },
            {
              text: '禁用',
              iifBehavior: 'disabled',
              iif: record => record.scheduledStatus !== 'started',
              click: _record => {
                this.disableJob(_record);
              }
            }
          ]
        }
      ]
    }
  ];

  restarting = false;
  restartAllJob() {
    this.msgSrv.form_confirm2(
      `请确认是否要重启「${this.currentGroup.groupName}」所有作业？`,
      '点击‘确定’立马重启',
      () => {
        this.restarting = true;
        this.sysSrv.restartAllJob().subscribe(res => {
          this.restarting = false;
          console.log('restartAllJob', res);
          if (res.status) {
            this.loadJobList(true);
            this.msgSrv.msg_success('成功重启调度');
          } else {
            this.msgSrv.msg_error(res.msg);
          }
        });
      },
      () => {
        return;
      },
      500,
      'confirm'
    );
  }

  startJobByGroup() {
    this.msgSrv.form_confirm2(
      `请确认是否要启动「${this.currentGroup.groupName}」所有作业？`,
      '点击‘确定’立马启动',
      () => {
        this.restarting = true;
        this.sysSrv.startJobByGroup(this.currentGroup.groupCode).subscribe(res => {
          this.restarting = false;
          console.log('startJobByGroup', res);
          if (res.status) {
            this.loadJobList(true);
            this.msgSrv.msg_success('成功开启当前分组所有作业');
          } else {
            this.msgSrv.msg_error(res.msg);
          }
        });
      },
      () => {
        return;
      },
      500,
      'confirm'
    );
  }

  stopJobByGroup() {
    this.msgSrv.form_confirm2(
      `请确认是否要停止「${this.currentGroup.groupName}」所有作业？`,
      '点击‘确定’立马停止',
      () => {
        this.restarting = true;
        this.sysSrv.stopJobByGroup(this.currentGroup.groupCode).subscribe(res => {
          this.restarting = false;
          console.log('stopJobByGroup', res);
          if (res.status) {
            this.loadJobList(true);
            this.msgSrv.msg_success('成功停止当前分组所有作业');
          } else {
            this.msgSrv.msg_error(res.msg);
          }
        });
      },
      () => {
        return;
      },
      500,
      'confirm'
    );
  }
  startJob(record: any) {
    this.sysSrv.startJob(record.code).subscribe(res => {
      console.log('startJob', res);
      if (res.status) {
        this.loadJobList(true);
        this.msgSrv.msg_success(`成功开启 ${record.name} 作业`);
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }
  stopJob(record: any) {
    this.sysSrv.stopJob(record.code).subscribe(res => {
      console.log('stopJob', res);
      if (res.status) {
        this.loadJobList(true);
        this.msgSrv.msg_success(`成功停止 ${record.name} 作业`);
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }
  executeJob(record: any) {
    this.sysSrv.executeJob(record.code).subscribe(res => {
      console.log('executeJob', res);
      if (res.status) {
        this.loadJobList(true);
        this.msgSrv.msg_success(`${record.name} 执行完成`);
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }
  disableJob(record: any) {
    this.sysSrv.disableJob(record.code).subscribe(res => {
      console.log('disableJob', res);
      if (res.status) {
        this.loadJobList(true);
        this.msgSrv.msg_success(`${record.name} 已被禁用`);
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }
  deleteJob(record: any) {
    this.sysSrv.deleteJob(record.code).subscribe(res => {
      console.log('deleteJob', res);
      if (res.status) {
        this.msgSrv.msg_success(`${record.name} 已被删除`);
        this.jobList = this.jobList.filter(item => item.code !== record.code);
        this.jobListChange();
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }

  autoReSizeFixWindowHeight(): void {
    console.log('autoReSizeFixWindowHeight', window.innerHeight);
    window.addEventListener('resize', function () {
      document.documentElement.style.setProperty('--sider-max-height', `${window.innerHeight - 270}px`);
    });
    // 手动发布事件
    window.dispatchEvent(new Event('resize'));
  }

  pform: UntypedFormGroup = this.fb.group({
    code: [{ value: '', disabled: false }, [Validators.required]],
    name: [{ value: '', disabled: false }, [Validators.required]],
    groupCode: ['', [Validators.required]],
    remark: ['', []],
    cron: ['0 0 0/ * * *', [Validators.required]],
    executeType: ['url', [Validators.required]],
    executeName: ['', [Validators.required]],
    executeMethod: ['', [Validators.required]],
    executeParam: ['', []],
    numberOfThread: ['', []],
    numberOfData: ['', []],
    startupType: ['manual', [Validators.required]]
  });

  drawer_option = { width: '45%', visible: false, title: '作业详情' };

  drawer_close(): void {
    this.drawer_option.visible = false;
  }

  drawer_open(value: any) {
    if (value) {
      this.pform.patchValue(value);
    } else {
      if (this.currentGroup.groupCode != 'all') {
        this.pform.controls['groupCode'].setValue(this.currentGroup.groupCode);
      } else {
        this.pform.controls['groupCode'].setValue('');
      }
    }
    this.drawer_option.visible = true;
  }

  saveJob() {
    const body = this.pform.getRawValue();
    console.log('saveJob request', body);

    this.sysSrv.saveJob(body).subscribe(res => {
      console.log('saveJob', res);
      if (res.status) {
        this.loadJobList(true);
        this.msgSrv.msg_success('保存成功');
      } else {
        this.msgSrv.msg_error(res.msg);
      }
    });
  }

  viewLog(record: any = {}) {
    this.router.navigateByUrl(`/system/schedule/log?code=${record.code}`);
  }
}
